git-annex assist
authorJoey Hess <joeyh@joeyh.name>
Thu, 18 May 2023 18:37:29 +0000 (14:37 -0400)
committerJoey Hess <joeyh@joeyh.name>
Thu, 18 May 2023 18:37:43 +0000 (14:37 -0400)
assist: New command, which is the same as git-annex sync but with
new files added and content transferred by default.

(Also this fixes another reversion in git-annex sync,
--commit --no-commit, and --message were not enabled, oops.)

See added comment for why git-annex assist does commit staged
changes elsewhere in the work tree, but only adds files under
the cwd.

Note that it does not support --no-commit, --no-push, --no-pull
like sync does. My thinking is, why should it? If you want that
level of control, use git commit, git annex push, git annex pull.
Sync only got those options because pull and push were not split
out.

Sponsored-by: k0ld on Patreon
16 files changed:
CHANGELOG
CmdLine/GitAnnex.hs
Command/Add.hs
Command/Assist.hs [new file with mode: 0644]
Command/Assistant.hs
Command/Sync.hs
Command/Watch.hs
doc/git-annex-assist.mdwn [new file with mode: 0644]
doc/git-annex-assistant.mdwn
doc/git-annex-config.mdwn
doc/git-annex-sync.mdwn
doc/git-annex-watch.mdwn
doc/git-annex.mdwn
doc/todo/Having___39__git_annex_sync__39___optionally_add.mdwn
doc/todo/Having___39__git_annex_sync__39___optionally_add/comment_10_6d9ef10f9534c7b95ca58913cfe3b5fd._comment [new file with mode: 0644]
git-annex.cabal

index e43cdbccb8693d33643eab06683cc1d17e0c4dd9..2457dc0c364729fb190ff7809bb0e5f9a2ee301b 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -4,6 +4,8 @@ git-annex (10.20230408) UNRELEASED; urgency=medium
     Those plus a git commit are equivilant to git-annex sync.
     (Note that the new commands default to syncing content, unless
     annex.synccontent is explicitly set to false.)
+  * assist: New command, which is the same as git-annex sync but with
+    new files added and content transferred by default.
   * Many commands now quote filenames that contain unusual characters the
     same way that git does, to avoid exposing control characters to the terminal.
   * Support core.quotePath, which can be set to false to display utf8
index 5917606d6460e62a9cb05669a8a5de8092e2d6f7..8fcaf956e8c80b3c9e405ba73117b63b07f913d0 100644 (file)
@@ -100,6 +100,7 @@ import qualified Command.Ungroup
 import qualified Command.Config
 import qualified Command.Vicfg
 import qualified Command.Sync
+import qualified Command.Assist
 import qualified Command.Pull
 import qualified Command.Push
 import qualified Command.Mirror
@@ -147,6 +148,7 @@ cmds testoptparser testrunner mkbenchmarkgenerator = map addGitAnnexCommonOption
        , Command.Unlock.editcmd
        , Command.Lock.cmd
        , Command.Sync.cmd
+       , Command.Assist.cmd
        , Command.Pull.cmd
        , Command.Push.cmd
        , Command.Mirror.cmd
index 3a00aaa637ca00c711d8462e25ba8fc7ee2ad7d2..5f0daaab085683f0e1d55dfdf97231304908e953 100644 (file)
@@ -86,7 +86,10 @@ checkGitIgnoreSwitch = CheckGitIgnore <$>
                (help "Do not check .gitignore when adding files")
 
 seek :: AddOptions -> CommandSeek
-seek o = startConcurrency commandStages $ do
+seek o = startConcurrency commandStages (seek' o)
+
+seek' :: AddOptions -> CommandSeek
+seek' o = do
        largematcher <- largeFilesMatcher
        addunlockedmatcher <- addUnlockedMatcher
        annexdotfiles <- getGitConfigVal annexDotFiles 
diff --git a/Command/Assist.hs b/Command/Assist.hs
new file mode 100644 (file)
index 0000000..1ec83c1
--- /dev/null
@@ -0,0 +1,43 @@
+{- git-annex command
+ -
+ - Copyright 2023 Joey Hess <id@joeyh.name>
+ -
+ - Licensed under the GNU AGPL version 3 or higher.
+ -}
+
+module Command.Assist (cmd) where
+
+import Command
+import qualified Command.Sync
+import qualified Command.Add
+import Annex.CheckIgnore
+
+cmd :: Command
+cmd = withAnnexOptions [jobsOption, backendOption] $
+       command "assist" SectionCommon 
+               "add files and sync changes with remotes"
+               (paramRepeating paramRemote)
+               (myseek <--< Command.Sync.optParser Command.Sync.AssistMode)
+
+myseek :: Command.Sync.SyncOptions -> CommandSeek
+myseek o = startConcurrency transferStages $ do
+       -- Run before prepMerge so it adds only files in the current
+       -- directory and below, not new files elsewhere in the working
+       -- tree.
+       Command.Add.seek Command.Add.AddOptions
+               { Command.Add.addThese = []
+               , Command.Add.batchOption = NoBatch
+               , Command.Add.updateOnly = False
+               , Command.Add.largeFilesOverride = Nothing
+               , Command.Add.checkGitIgnoreOption = CheckGitIgnore (False)
+               , Command.Add.dryRunOption = DryRun False
+               }
+       
+       Command.Sync.prepMerge
+       Command.Sync.seek' o'
+  where
+       o'
+               | Command.Sync.contentOption o == Nothing 
+                       && Command.Sync.noContentOption o == Nothing =
+                               o { Command.Sync.contentOption = Just True }
+               | otherwise = o
index 66758f1941e860bca1c9ffd581975b7f4b7a713e..92db99664d521140c2b99206ed24a2b75f5fea18 100644 (file)
@@ -24,7 +24,7 @@ cmd :: Command
 cmd = dontCheck repoExists $ notBareRepo $
        noRepo (startNoRepo <$$> optParser) $
                command "assistant" SectionCommon
-                       "automatically sync changes"
+                       "daemon to add files and automatically sync changes"
                        paramNothing (seek <$$> optParser)
 
 data AssistantOptions = AssistantOptions
index dfdc3a83b252a23ccae7e3e7c6a0a0f9376d8695..eaad7f0eb25721d3742169f210b7943246acd87a 100644 (file)
@@ -12,6 +12,7 @@
 module Command.Sync (
        cmd,
        seek,
+       seek',
        CurrBranch,
        mergeConfig,
        merge,
@@ -94,7 +95,7 @@ cmd = withAnnexOptions [jobsOption, backendOption] $
                "synchronize local repository with remotes"
                (paramRepeating paramRemote) (seek <--< optParser SyncMode)
 
-data OperationMode = SyncMode | PullMode | PushMode
+data OperationMode = SyncMode | PullMode | PushMode | AssistMode
        deriving (Eq, Show)
 
 data SyncOptions = SyncOptions
@@ -151,15 +152,15 @@ optParser mode desc = SyncOptions
                ( long "not-only-annex"
                <> help "operate on git branches as well as annex"
                )
-       <*> unlessmode SyncMode False (switch
+       <*> unlessmode [SyncMode] False (switch
                ( long "commit"
                <> help "commit changes to git"
                ))
-       <*> unlessmode SyncMode True (switch
+       <*> unlessmode [SyncMode] True (switch
                ( long "no-commit"
                <> help "avoid git commit" 
                ))
-       <*> unlessmode SyncMode Nothing (optional (strOption
+       <*> unlessmode [SyncMode, AssistMode] Nothing (optional (strOption
                ( long "message" <> short 'm' <> metavar "MSG"
                <> help "commit message"
                )))
@@ -169,12 +170,14 @@ optParser mode desc = SyncOptions
                        )
                PullMode -> pure True
                PushMode -> pure False
+               AssistMode -> pure True
        <*> case mode of
                SyncMode -> invertableSwitch "push" True
                        ( help "avoid git pushes to remotes" 
                        )
                PullMode -> pure False
                PushMode -> pure True
+               AssistMode -> pure True
        <*> optional (flag' True 
                ( long "content"
                <> help "transfer annexed file contents" 
@@ -190,25 +193,24 @@ optParser mode desc = SyncOptions
                <> help "transfer contents of annexed files in a given location"
                <> metavar paramPath
                ))
-       <*> whenmode PullMode False (switch
+       <*> whenmode [PullMode] False (switch
                ( long "cleanup"
                <> help "remove synced/ branches from previous sync"
                ))
        <*> optional parseAllOption
-       <*> whenmode PushMode False (invertableSwitch "resolvemerge" True
+       <*> whenmode [PushMode] False (invertableSwitch "resolvemerge" True
                ( help "do not automatically resolve merge conflicts"
                ))
-       <*> case mode of
-               PushMode -> pure False
-               _ -> parseUnrelatedHistoriesOption
+       <*> whenmode [PushMode] False
+               parseUnrelatedHistoriesOption
        <*> pure mode
   where
-       unlessmode m v a
-               | mode /= m = pure v
-               | otherwise = a
        whenmode m v a
-               | mode == m = pure v
+               | mode `elem` m = pure v
                | otherwise = a
+       unlessmode m v a
+               | mode `elem` m = a
+               | otherwise = pure v
 
 parseUnrelatedHistoriesOption :: Parser Bool
 parseUnrelatedHistoriesOption = 
@@ -240,8 +242,9 @@ instance DeferredParseClass SyncOptions where
 seek :: SyncOptions -> CommandSeek
 seek o = do
        warnSyncContentTransition o
-
+       
        prepMerge
+       
        startConcurrency transferStages (seek' o)
 
 seek' :: SyncOptions -> CommandSeek
@@ -828,6 +831,7 @@ seekSyncContent o rs currbranch = do
                        SyncMode -> "sync"
                        PullMode -> "pull"
                        PushMode -> "push"
+                       AssistMode -> "assist"
 
        gofile bloom mvar _ f k = 
                go (Right bloom) mvar (AssociatedFile (Just f)) k
@@ -1044,7 +1048,7 @@ cleanupRemote remote (Just b, _) =
 shouldSyncContent :: SyncOptions -> Annex Bool
 shouldSyncContent o
        | fromMaybe False (noContentOption o) = pure False
-       -- For git-annex pull and git-annex push
+       -- For git-annex pull and git-annex push and git-annex assist,
        -- annex.syncontent defaults to True unless set
        | operationMode o /= SyncMode = annexsynccontent True
        | fromMaybe False (contentOption o) || not (null (contentOfOption o)) = pure True
index 7a613ad4608a87af5826a3498180315fc5de4964..340559d2b64f86dcc34cbaadde39f252aae23fc7 100644 (file)
@@ -14,7 +14,7 @@ import Utility.HumanTime
 cmd :: Command
 cmd = notBareRepo $
        command "watch" SectionCommon 
-               "watch for changes and autocommit"
+               "daemon to watch for changes and autocommit"
                paramNothing (seek <$$> const (parseDaemonOptions True))
 
 seek :: DaemonOptions -> CommandSeek
diff --git a/doc/git-annex-assist.mdwn b/doc/git-annex-assist.mdwn
new file mode 100644 (file)
index 0000000..35be1d8
--- /dev/null
@@ -0,0 +1,57 @@
+# NAME
+
+git-annex assist - add files and sync changes with remotes
+
+# SYNOPSIS
+
+git annex assist `[remote ...]`
+
+# DESCRIPTION
+
+This command assists you in checking files into the repository
+and syncing with remotes. It's the simplest possible way to use git-annex
+at the command line, since only this one command needs to be run on a
+regular basis.
+
+This command first adds any new files (in the current directory and
+its children) to the repository, and commits those as well as any
+modified files. Then it does the equivilant of running
+[[git-annex-pull](1) followed by [[git-annex-push]](1).
+
+To block some files from being added to the repository, use `.gitignore`
+files.
+
+By default, all files that are added are added to the annex, the same
+as when you run `git annex add`. If you configure annex.largefiles,
+files that it does not match will instead be added with `git add`.
+
+# OPTIONS
+
+* `--message=msg`
+
+  Use this option to specify a commit message.
+
+* Also all options supported by [[git-annex-pull]](1) and
+  [[git-annex-push]](1) can be used.
+
+* Also the [[git-annex-common-options]](1) can be used.
+
+# SEE ALSO
+
+[[git-annex]](1)
+
+[[git-annex-add]](1)
+
+[[git-annex-pull]](1)
+
+[[git-annex-push]](1)
+
+[[git-annex-sync]](1)
+
+[[git-annex-assistant]](1)
+
+# AUTHOR
+
+Joey Hess <id@joeyh.name>
+
+Warning: Automatically converted into a man page by mdwn2man. Edit with care.
index c0254f61561bf1083bd347fcaf30838f73466418..076c26f37fd63102726735796a33882ccae9feb5 100644 (file)
@@ -1,6 +1,6 @@
 # NAME
 
-git-annex assistant - automatically sync changes
+git-annex assistant - daemon to add files and automatically sync changes
 
 # SYNOPSIS
 
@@ -58,6 +58,8 @@ files that it does not match will instead be added with `git add`.
 
 [[git-annex-watch]](1)
 
+[[git-annex-assist]](1)
+
 [[git-annex-schedule]](1)
 
 For more details about the git-annex assistant, see
index 6583cf07392e40a0552820fce6d9c3248bceaeae..a0499d1c15577104194a80dfab3c13bfd18503fe 100644 (file)
@@ -35,6 +35,18 @@ looks for these.
   It is an expression that matches the large files, eg
   "`include=*.mp3 or largerthan(500kb)`".
   See [[git-annex-matching-expression]](1) for details on the syntax.
+  
+  This configures the behavior of both git-annex and git when adding
+  files to the repository. By default, `git-annex add` adds all files
+  to the annex (except dotfiles), and `git add` adds files to git
+  (unless they were added to the annex previously).
+  When annex.largefiles is configured, both
+  `git annex add` and `git add` will add matching large files to the
+  annex, and the other files to git.
+
+  Other git-annex commands also honor annex.largefiles, including
+  `git annex import`, `git annex addurl`, `git annex importfeed`,
+  `git-annex assist`, and the `git-annex assistant`.
 
   This sets a default, which can be overridden by annex.largefiles
   attributes in `.gitattributes` files, or by `git config`.
@@ -64,8 +76,9 @@ looks for these.
 
 * `annex.autocommit`
 
-  Set to false to prevent the `git-annex assistant` and `git-annex sync`
-  from automatically committing changes to files in the repository.
+  Set to false to prevent the `git-annex assistant`, `git-annex assist`
+  and `git-annex sync` from automatically committing changes to files
+  in the repository.
    
   This sets a default, which can be overridden by annex.autocommit
   in `git config`.
index 8e0db80410a4cccbee9830858c1d03dc31bebeb0..d1c02def0a172a7a4fac3ed8645a0680a53256c8 100644 (file)
@@ -74,6 +74,8 @@ content by default. That will change in a future version of git-annex,
 
 [[git-annex-push]](1)
 
+[[git-annex-assist]](1)
+
 # AUTHOR
 
 Joey Hess <id@joeyh.name>
index b65b4dc657c46f665077652f1656e58a531d6fcc..7f82cbb62f0afb3d65ec469acc36b480e54656cd 100644 (file)
@@ -1,6 +1,6 @@
 # NAME
 
-git-annex watch - watch for changes
+git-annex watch - daemon to watch for changes
 
 # SYNOPSIS
 
index 78427a4ba5ec984c3812bc9175e2bfa4cb9bbc57..f071e7895c731fb23c98a1d55511e5727099f39c 100644 (file)
@@ -132,6 +132,12 @@ content from the key-value store.
   
   See [[git-annex-sync]](1) for details.
 
+* `assist [remote ...]`
+
+  Add files and sync changes with remotes.
+  
+  See [[git-annex-assist]](1) for details.
+
 * `mirror [path ...] [--to=remote|--from=remote]`
 
   Mirror content of files to/from another repository.
@@ -182,13 +188,13 @@ content from the key-value store.
 
 * `watch`
 
-  Watch for changes and autocommit.
+  Daemon to watch for changes and autocommit.
   
   See [[git-annex-watch]](1) for details.
 
 * `assistant`
 
-  Automatically sync folders between devices.
+  Daemon to automatically sync changes.
 
   See [[git-annex-assistant]](1) for details.
 
@@ -904,8 +910,8 @@ repository, using [[git-annex-config]]. See its man page for a list.)
   annex, and the other files to git.
 
   Other git-annex commands also honor annex.largefiles, including
-  `git annex import`, `git annex addurl`, `git annex importfeed`
-  and the assistant.
+  `git annex import`, `git annex addurl`, `git annex importfeed`,
+  `git-annex assist`, and the `git-annex assistant`.
 
 * `annex.dotfiles`
 
@@ -1177,7 +1183,7 @@ repository, using [[git-annex-config]]. See its man page for a list.)
 
   Set to false to prevent merge conflicts in the checked out branch
   being automatically resolved by the `git-annex assitant`,
-  `git-annex sync`, `git-annex pull`, `git-annex merge`,
+  `git-annex assist`, `git-annex sync`, `git-annex pull`, `git-annex merge`,
   and the git-annex post-receive hook.
 
   To configure the behavior in all clones of the repository,
@@ -1188,16 +1194,17 @@ repository, using [[git-annex-config]]. See its man page for a list.)
   Set to true to make `git-annex sync` default to transferring
   annexed content.
 
-  Set to false to prevent `git-annex pull` and `git-annex push` from
-  transferring annexed content.
+  Set to false to prevent `git-annex assist`, `git-annex pull` and
+  `git-annex push` from transferring annexed content.
 
   To configure the behavior in all clones of the repository,
   this can be set in [[git-annex-config]](1).
 
 * `annex.synconlyannex`
 
-  Set to true to make git-annex sync, git-annex pull, and git-annex push
-  default to only operating on the git-annex branch and annexed content.
+  Set to true to make `git-annex assist`, `git-annex sync`, 
+  `git-annex pull`, and `git-annex push` default to only operating
+  on the git-annex branch and annexed content.
 
   To configure the behavior in all clones of the repository,
   this can be set in [[git-annex-config]](1).
@@ -1377,8 +1384,9 @@ Remotes are configured using these settings in `.git/config`.
   Or, it could be used if the network connection between two
   repositories is too slow to be used normally.
 
-  This does not prevent git-annex sync, git-annex pull, git-annex push,
-  or the git-annex assistant from operating on the git repository.
+  This does not prevent `git-annex sync`, `git-annex pull`, `git-annex push`,
+  `git-annex assist` or the `git-annex assistant` from operating on the
+  git repository.
 
 * `remote.<name>.annex-ignore-command`
 
@@ -1388,8 +1396,9 @@ Remotes are configured using these settings in `.git/config`.
 
 * `remote.<name>.annex-sync`
 
-  If set to `false`, prevents git-annex sync (and git-annex pull, git-annex
-  sync, and the git-annex assistant) from operating on this remote by default.
+  If set to `false`, prevents `git-annex sync` (and `git-annex pull`, 
+  `git-annex push`, `git-annex assist`, and the `git-annex assistant`)
+  from operating on this remote by default.
 
 * `remote.<name>.annex-sync-command`
 
@@ -1399,20 +1408,22 @@ Remotes are configured using these settings in `.git/config`.
 
 * `remote.<name>.annex-pull`
 
-  If set to `false`, prevents git-annex sync, git-annex pull,
-  (and the git-annex assistant etc) from ever pulling (or fetching)
-  from the remote.
+  If set to `false`, prevents `git-annex pull`, `git-annex sync`,
+  `git-annex assist` and the `git-annex assistant` from ever pulling
+  (or fetching) from the remote.
 
 * `remote.<name>.annex-push`
 
-  If set to `false`, prevents git-annex sync, git-annex push,
-  (and the git-annex assistant etc) from ever pushing to the remote.
+  If set to `false`, prevents `git-annex push`, `git-annex sync`,
+  `git-annex assist` and the `git-annex assistant` from ever pushing
+  to the remote.
 
 * `remote.<name>.annex-readonly`
 
   If set to `true`, prevents git-annex from making changes to a remote.
-  This both prevents git-annex sync from pushing changes, and prevents
-  storing or removing files from read-only remote.
+  This prevents `git-annex sync` and `git-annex assist` from pushing
+  changes to a git repository. And it prevents storing or removing
+  files from read-only remote.
 
 * `remote.<name>.annex-verify`, `annex.verify`
 
@@ -1434,9 +1445,11 @@ Remotes are configured using these settings in `.git/config`.
   When set to eg, "master:subdir", the special remote tracks only
   the subdirectory of that branch.
 
-  `git-annex sync --content` will import changes from the remote and 
-  merge them into the annex-tracking-branch. They also export changes
-  made to the branch to the remote.
+  Setting this enables some other command to work with these special
+  remotes: `git-annex pull` will import changes from the remote and merge them into
+  the annex-tracking-branch. And `git-annex push` will export changes to
+  the remote. Higher-level commands `git-annex sync --content`
+  and `git-annex assist` both import and export.
 
 * `remote.<name>.annex-export-tracking`
 
@@ -1928,8 +1941,9 @@ Remotes are configured using these settings in `.git/config`.
 
 * `annex.autocommit`
 
-  Set to false to prevent the git-annex assistant and git-annex sync
-  from automatically committing changes to files in the repository.
+  Set to false to prevent the `git-annex assistant`, `git-annex assist`, 
+  and `git-annex sync` from automatically committing changes to files in
+  the repository.
 
   To configure the behavior in all clones of the repository,
   this can be set in [[git-annex-config]](1).
index b43ad2988bca2ac2bcde72d5c7dea9bfedeb6023..5a357bb233e52c285c44ed88d3e3993c2d843428 100644 (file)
@@ -34,3 +34,5 @@ while true;do git annex sync --content;done
 What do you think?
 
 Cheers, Yann
+
+> [[done]] as `git-annex assist` --[[Joey]]
diff --git a/doc/todo/Having___39__git_annex_sync__39___optionally_add/comment_10_6d9ef10f9534c7b95ca58913cfe3b5fd._comment b/doc/todo/Having___39__git_annex_sync__39___optionally_add/comment_10_6d9ef10f9534c7b95ca58913cfe3b5fd._comment
new file mode 100644 (file)
index 0000000..be5c983
--- /dev/null
@@ -0,0 +1,31 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 10"""
+ date="2023-05-18T17:45:44Z"
+ content="""
+Implementing `git-annex assist` now...
+
+A tricky point is, should it add files only in the current directory and
+below, or all files in the repository? Note that the assistant can be run
+in a directory and it will only add changed/new files in that directory,
+although it can receive pulls that change files in other directories
+(and will then download those files content).
+
+OTOH, `git-annex sync` commits all changes, not only those in the
+current directory. (The assistant does in some circumstanges commit
+changes made outside the current directory. Its behavior is a bit
+inconsistent in this area.)
+
+So I think it makes sense for `git-annex assist` to only add files in the
+current directory by default. (Of course an option like -A could be added
+later.)
+
+And while I'm a bit ambivilant about it, I'm making it commit all staged
+changes, not only those in the current directory. As well as following the
+behavior of `git-annex sync` and to an extent the assistant, it seems to 
+me that if you run `git-annex add ../foo; git-annex assist`, you are
+intentionally building up a commit that includes file "foo". The same
+as if you ran `git-annex add ../foo; git-annex add .` ... If you're not,
+and you care about what files get added in what commit, you can of course
+commit manually.
+"""]]
index c4122d3de73b1a446402c42ad1829f4a26cfc0e2..22342240fc51e0a842d0e6123cc5c60e7c4b9b76 100644 (file)
@@ -45,6 +45,7 @@ Extra-Source-Files:
   doc/git-annex-addunused.mdwn
   doc/git-annex-addurl.mdwn
   doc/git-annex-adjust.mdwn
+  doc/git-annex-assist.mdwn
   doc/git-annex-assistant.mdwn
   doc/git-annex-backends.mdwn
   doc/git-annex-calckey.mdwn
@@ -709,6 +710,7 @@ Executable git-annex
     Command.AddUnused
     Command.AddUrl
     Command.Adjust
+    Command.Assist
     Command.Benchmark
     Command.CalcKey
     Command.CheckPresentKey